<?php
namespace app\common\tool;


class SFDeliver
{
    protected $sfServiceCode_test;//HZXYKJ
    protected $sfKeySecret_test;//JjXFYiap37BDSBXk
    protected $sfWebService_test;//http://bspoisp.sit.sf-express.com:11080/bsp-oisp/sfexpressService
    protected $sfServiceCode;//BSPdevelop
    protected $sfKeySecret;//j8DzkIFgmlomPt0aLuwU
    protected $sfWebService_port80;//http://bsp-ois.sit.sf-express.com:9080/bsp-ois/ws/sfexpressService?wsdl
    protected $sfWebService_port443;//https://bsp-ois.sit.sf-express.com:9443/bsp-ois/ws/sfexpressService?wsdl
    protected $sfPostService_port80;//http://bsp-ois.sit.sf-express.com:9080/bsp-ois/sfexpressService
    protected $sfPostService_port443;//http://bsp-ois.sit.sf-express.com:9443/bsp-ois/sfexpressService
    protected $custid;//5717085362
    public $xml;
    public $verifyCode;

    public function __construct()
    {
        $this->sfServiceCode_test = "HZBXKJ";
        $this->sfKeySecret_test = "wITgj0TiNaml1gGp";
        $this->sfWebService_test = "http://bspoisp.sit.sf-express.com:11080/bsp-oisp/ws/sfexpressService?wsdl";
        //$this->sfServiceCode = "HZBXKJ";//BSPdevelop
        $this->sfServiceCode = "5717085362";
        //$this->sfKeySecret = "wITgj0TiNaml1gGp";//j8DzkIFgmlomPt0aLuwU
        $this->sfKeySecret = "Tl7dIpAgVEGlyJOKfOCJQ3Eb1rchTiAD";
        $this->sfWebService_port80 = "http://bsp-ois.sit.sf-express.com:9080/bsp-ois/ws/sfexpressService?wsdl";
        //$this->sfPostService_port80 = "http://bspoisp.sit.sf-express.com:11080/bsp-oisp/sfexpressService";
        $this->sfWebService_port443 = "http://bsp-ois.sit.sf-express.com:9443/bsp-ois/ws/sfexpressService?wsdl";
        //$this->sfPostService_port80 = "http://bsp-ois.sit.sf-express.com:9080/bsp-ois/sfexpressService";
        $this->sfPostService_port80 = "http://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService";
        //$this->sfPostService_port80 = "http://bsp-oisp.sf-express.com/bsp-oisp/ws/expressService?wsdl=";
        $this->sfPostService_port443 = "http://bsp-ois.sit.sf-express.com:9443/bsp-ois/sfexpressService";
        $this->custid = '5717085362';//9999999999  5717085362
        try {
            $this->xml = '';
        }catch (Exception $e) {
            return $this->json_export(0, '顺丰工具初始化失败：'.$e->getMessage(), '');
        }
    }

    //json返回
    private function json_export($status,$msg,$data=[]){
        $ret_arr = [
            'status' => $status,//0错误 1成功
            'msg' => $msg,
            'data' => (empty($data) ? "" : $data),
        ];
        return json_encode($ret_arr);
    }

    private function createCode(){
        $xml = $this->xml;
        $key = $this->sfKeySecret;
        $code_md5 = md5($xml.$key,true);
        $code = base64_encode($code_md5);
        return $code;
    }

    private function createCode_test(){
        $xml = $this->xml;
        $key = $this->sfKeySecret_test;
        $code_md5 = md5($xml.$key,true);
        $code = base64_encode($code_md5);
        return $code;
    }

    //sf下单
    public function createOrder($data = [])
    {
        $contact = $data['user_name'];
        $tel = $data['mobile'];
        $address = $data['province'].$data['city'].$data['district'].$data['address'];
        $orderid = $data['order_sn'];
        $cargo_count = $data['book_num'];
        $this->xml.=
            '<?xml version="1.0" encoding="UTF-8"?>
            <Request service="OrderService" lang="zh-CN">
            <Head>'.$this->sfServiceCode.'</Head>
            <Body>
                <Order
                orderid="'.$orderid.'"
                is_gen_bill_no="1"
                j_company="博享科技有限公司"
                j_contact="博鸟绘本"
                j_tel="0571-86113050"
                j_mobile="17858616628"
                j_province="浙江省"
                j_city="杭州市"
                j_county="余杭区"
                j_address="杭州未来研创园A幢207室"
                d_company="个人"
                d_contact="'.$contact.'"
                d_tel="'.$tel.'"
                d_mobile="'.$tel.'"
                d_address="'.$address.'"
                custid="'.$this->custid.'"
                parcel_quantity="1"
                express_type="2"
                pay_method="1">
                <Cargo
                name="绘本"
                count="'.$cargo_count.'"
                unit="本">
                </Cargo>
                <Extra
                e1="博鸟绘本"/>
                </Order>
            </Body>
            </Request>';
        $this->verifyCode = $this->createCode();
        $data=[
            'xml'=>$this->xml,
            'verifyCode'=>$this->verifyCode
        ];
        $parambody =  http_build_query($data, '', '&');
        $res = $this->sf_post($this->sfPostService_port80,$parambody);
        if(!$res){
            return Message(400,'error','获取超时，请重试','');
        }
        $result = self::xmlToArray($res);
        //var_dump($result);
        if($result['Head'] == "ERR"){
            return $this->json_export(0, "下单失败：".$result['ERROR'], '');
        }else{
            $mailno = $result['Body']['OrderResponse']['@attributes']['mailno'];
            return $this->json_export(1, "下单成功", ['mailno'=>$mailno]);
        }
    }

    //sf下单test
    public function createOrder_test($data = [])
    {
        $contact = $data['user_name'];
        $tel = $data['mobile'];
        $address = $data['province'].$data['city'].$data['district'].$data['address'];
        $orderid = $data['order_sn'];
        $cargo_count = $data['book_num'];
        $this->xml.=
            '<?xml version="1.0" encoding="UTF-8"?>
            <Request service="OrderService" lang="zh-CN">
            <Head>'.$this->sfServiceCode_test.'</Head>
            <Body>
                <Order
                orderid="'.$orderid.'"
                is_gen_bill_no="1"
                j_company="博享科技有限公司"
                j_contact="博鸟绘本"
                j_tel="0571-86113050"
                j_province="浙江省"
                j_city="杭州"
                j_county="余杭区"
                j_address="杭州未来研创园A幢207室"
                d_company="个人"
                d_contact="'.$contact.'"
                d_tel="'.$tel.'"
                d_address="'.$address.'"
                parcel_quantity="1"
                express_type="2"
                pay_method="1"
                need_return_tracking_no="1">
                <Cargo
                name="绘本"
                count="'.$cargo_count.'"
                unit="本">
                </Cargo>
                <Extra
                e1="博鸟绘本"/>
                </Order>
            </Body>
            </Request>';
        $this->verifyCode = $this->createCode_test();
        $data=[
            'xml'=>$this->xml,
            'verifyCode'=>$this->verifyCode
        ];
        $parambody =  http_build_query($data, '', '&');
        $res = $this->sf_post($this->sfWebService_test,$parambody);
        if(!$res){
            return Message(400,'error','获取超时，请重试','');
        }
        $result = self::xmlToArray($res);
        if($result['Head'] == "ERR"){
            return $this->json_export(0, "下单失败：".$result['ERROR'], '');
        }else{
            $mailno = $result['Body']['OrderResponse']['@attributes']['mailno'];
            return $this->json_export(1, "下单成功", ['mailno'=>$mailno]);
        }
    }

    //查询订单快递编号(业务还未配置)
    public function searchOrder($data = []){
        $orderid = $data['order_sn'];//$data['order_sn'] 20180124141026444233
        $this->xml.=
            '<?xml version="1.0" encoding="UTF-8"?>
            <Request service="OrderSearchService" lang="zh-CN">
            <Head>'.$this->sfServiceCode.'</Head>
            <Body>
                <OrderSearch orderid="'.$orderid.'"/>
            </Body>
            </Request>';
        $this->verifyCode = $this->createCode();
        $data=[
            'xml'=>$this->xml,
            'verifyCode'=>$this->verifyCode
        ];
        //dump($data);
        $parambody =  http_build_query($data, '', '&');
        $res = $this->sf_post($this->sfPostService_port80,$parambody);
        //$res = $this->sf_soap($this->sfPostService_port80,$parambody);
        if(!$res){
            return Message(400,'error','获取超时，请重试','');
        }
        $result = self::xmlToArray($res);
        if($result['Head'] == "ERR"){
            if(is_array($result['ERROR'])){
                return $this->json_export(0, "查询失败：".$result['ERROR']['@attributes']['code'], '');
            }else{
                return $this->json_export(0, "查询失败：".$result['ERROR'], '');
            }
        }else{
            $mailno = $result['Body']['OrderResponse']['@attributes']['mailno'];
            return $this->json_export(1, "查询成功", ['mailno'=>$mailno]);
        }
    }

    //消单
    public function deleteOrder($data = []){
        $orderid = $data['order_sn'];
        $this->xml.=
            '<?xml version="1.0" encoding="UTF-8"?>
            <Request service="OrderRvsCancelService" lang="zh-CN">
            <Head>'.$this->sfServiceCode.'</Head>
            <Body>
                <Order
                orderid="'.$orderid.'">
                </Order>
            </Body>
            </Request>';
        $this->verifyCode = $this->createCode();
        $data=[
            'xml'=>$this->xml,
            'verifyCode'=>$this->verifyCode
        ];
        $parambody =  http_build_query($data, '', '&');
        $res = $this->sf_post($this->sfPostService_port80,$parambody);
        if(!$res){
            return Message(400,'error','获取超时，请重试','');
        }
        $result = self::xmlToArray($res);
        if($result['Head'] == "ERR"){
            if(is_array($result['ERROR'])){
                return $this->json_export(0, "消单失败：".$result['ERROR']['@attributes']['code'], '');
            }else{
                return $this->json_export(0, "消单失败：".$result['ERROR'], '');
            }
        }else{
            return $this->json_export(1, "消单成功", ['order_sn'=>$orderid]);
        }
    }

    function sf_post($url,$params)
    {
        $curlObj = curl_init();
        curl_setopt($curlObj, CURLOPT_URL, $url);
        curl_setopt($curlObj, CURLOPT_RETURNTRANSFER, 1); //curl_exec将结果返回,而不是执行
        curl_setopt($curlObj, CURLOPT_HTTPHEADER, array("Content-Type: application/x-www-form-urlencoded;charset=UTF-8"));
        curl_setopt($curlObj, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curlObj, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curlObj, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

        curl_setopt($curlObj, CURLOPT_CUSTOMREQUEST, 'POST');

        curl_setopt($curlObj, CURLOPT_POST, true);
        curl_setopt($curlObj, CURLOPT_POSTFIELDS, $params);
        curl_setopt($curlObj, CURLOPT_ENCODING, 'gzip');
        //var_dump(curl_getinfo($curlObj));
        $res = @curl_exec($curlObj);
        //var_dump(curl_getinfo($curlObj));
        curl_close($curlObj);

        if ($res === false) {
            $errno = curl_errno($curlObj);
            if ($errno == CURLE_OPERATION_TIMEOUTED) {
                $msg = "Request Timeout:   seconds exceeded";
            } else {
                $msg = curl_error($curlObj);
            }
            echo $msg;
            $e = new XN_TimeoutException($msg);
            throw $e;
        }
        return $res;
    }

    function sf_soap($url,$params)
    {
        $client = new \SoapClient ($url);
        $client->soap_defencoding = 'utf-8';
        $client->xml_encoding = 'utf-8';
        //$param = array('arg0'=>$params['xml'],'arg1'=>$params['verifyCode']);//参数拼接xml字符串
        $param = array('arg0'=>$params);
        var_dump($param);
        $result = $client->sfexpressService($param);//返回值
        //$result = $client->__soapCall('sfexpressService',$param);//返回值
        var_dump($result);
    }

    /**
     * XML文档转为数组
     * @param string $xml XML文档字符串
     * @return array
     */
    public static function xmlToArray($xml) {
        return $xml ? self::xmlToArrayElement(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)) : array();
    }

    /**
     * xml文档转为数组元素
     * @param obj $xmlobject XML文档对象
     * @return array
     */
    public static function xmlToArrayElement($xmlobject) {
        $data = array();
        foreach ((array) $xmlobject as $key => $value) {
            $data[$key] = !is_string($value) ? self::xmlToArrayElement($value) : $value;
        }
        return $data;
    }

}